from django import forms
from django_redis import get_redis_connection
from django.core.validators import RegexValidator

from users.models import Users

# 创建手机号的正则校验器
mobile_validator = RegexValidator(r"1[3-9]\d{9}$", "手机号码格式不正确")


class CheckImgCodeForm(forms.Form):
    """
    check image code
    """
    phone = forms.CharField(max_length=11, min_length=11, validators=[mobile_validator],
                             error_messages={"min_length": "手机号长度有误",
                                             "max_length": "手机号长度有误", "required": "手机号不能为空"})

    image_code_id = forms.UUIDField(error_messages={"required": "图片uuid不能为空"})

    text = forms.CharField(max_length=4, min_length=4,
                           error_messages={"min_length": "图片验证码长度有误", "max_length": "图片验证码长度有误",
                                           "required": "图片验证码不能为空"})

    def clean_mobile(self):
        tel = self.cleaned_data.get('phone')
        if Users.objects.filter(phone=tel).count():
            raise forms.ValidationError("手机号码已注册，请重新输入")

        return tel

    def clean(self):  # 联合校验
        cleaned_data = super().clean()
        mobile_num = cleaned_data.get("phone")
        image_uuid = cleaned_data.get("image_code_id")
        image_text = cleaned_data.get("text")
        # 1.获取图片验证码
        con_redis = get_redis_connection(alias="verify_codes")  # 连接redis
        img_key = "img_{}".format(image_uuid).encode("utf-8")  # 拼接保存在redis验证码的key。redis只能保存为二进制，需要编码

        real_image_code = con_redis.get(img_key).decode("utf-8")  # 取出redis中key对应value，也就是真实的验证码
        print(real_image_code)
        print(img_key)

        # 2.判断用户输入的图片验证码是否正确
        if not real_image_code:
            raise forms.ValidationError("验证失败！请重新输入！")
        elif real_image_code != image_text:
            raise forms.ValidationError("验证码不一致，请重新输入！")

        # 3.判断在60秒内是否有发送短信的记录
        sms_flag_fmt = "sms_flag_{}".format(mobile_num).encode("utf-8")  # 是否有过短信验证的标签
        sms_flag = con_redis.get(sms_flag_fmt)

        if sms_flag:
            raise forms.ValidationError("获取短信过于频繁")
